package org.wheel.base.stmt;

import org.apache.commons.collections4.map.CaseInsensitiveMap;
import org.apache.commons.lang3.ClassUtils;
import org.dom4j.Element;
import org.wheel.base.utils.StringUtils;

/**
 * @author klaus
 * @date 2021/4/2 华小勇 22:58
 */
public class SqlStatement {

    private boolean modify;

    private boolean insert;

    private boolean update;

    private boolean select;

    private boolean nativeQuery;

    private Class<?> resultType;

    private static CaseInsensitiveMap resultTypes;

    static {
        resultTypes = new CaseInsensitiveMap();
        
        resultTypes.put("map", java.util.Map.class);
    }

    private Element element;

    public SqlStatement(Element element) {
        this.element = element;
        this.init();
    }

    void init() {
        String nn = element.getName();
        this.setInsert(StringUtils.containsIgnoreCase(nn, "insert"));
        this.setUpdate(StringUtils.containsIgnoreCase(nn, "update"));

        String nat = element.attributeValue("native");
        this.setNativeQuery((nat != null && "true".equalsIgnoreCase(nat) || this.isInsert()));
        this.setSelect(StringUtils.containsIgnoreCase(nn, "select"));
        this.setModify(!this.select);
        String rt = element.attributeValue("resultType");
        if (StringUtils.isNotBlank(rt)) {
            this.resultType = (Class<?>) resultTypes.computeIfAbsent(rt, (key) -> {
                try {
                    return ClassUtils.getClass(String.valueOf(key));
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                return null;
            });
        }
    }

    public boolean isNativeQuery() {
        return nativeQuery;
    }

    public void setNativeQuery(boolean nativeQuery) {
        this.nativeQuery = nativeQuery;
    }

    public boolean isModify() {
        return modify;
    }

    public void setModify(boolean modify) {
        this.modify = modify;
    }

    public boolean isInsert() {
        return insert;
    }

    public void setInsert(boolean insert) {
        this.insert = insert;
    }

    public boolean isUpdate() {
        return update;
    }

    public void setUpdate(boolean update) {
        this.update = update;
    }

    public boolean isSelect() {
        return select;
    }

    public void setSelect(boolean select) {
        this.select = select;
    }

    public Element getElement() {
        return element;
    }

    public void setElement(Element element) {
        this.element = element;
    }

    public Class<?> getResultType() {
        return resultType;
    }

    public void setResultType(Class<?> resultType) {
        this.resultType = resultType;
    }

    public String execute(Object root) {
        StringBuffer SB = new StringBuffer();
        OrmSqlUtils.build(element, SB, root);
        return SB.toString();
    }

}
